﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using Innova.Microfinanzas.BusinessEntities;
using Innova.Microfinanzas.Business.Utils;
using MyCommerce.Business.Stores;
using MyCommerce.Business.GeneralParameters;
using Innova.Microfinanzas.BusinessEntities.SystemEnums;
namespace Innova.Microfinanzas.Business.UsersAndSecurity
{
    public class UserManager
    {
        private MyCommerceEntities vContext;

        public UserManager()
        {
            if (vContext == null)
            {
                vContext = new MyCommerceEntities();
                vContext.ContextOptions.LazyLoadingEnabled = false;
            }
        }

        public UserManager(bool lazyLoad)
        {
            if (vContext == null)
            {
                vContext = new MyCommerceEntities();
                vContext.ContextOptions.LazyLoadingEnabled = lazyLoad;
            }
        }

        public void CreateUser(User objUser)
        {
            objUser.Password = HashHelper.GeneratePasswordHash(objUser.Password);
            vContext.AddObject("User", objUser);
            vContext.SaveChanges();
        }

        public void UpdateUser(User objUser)
        {
            var vResult = (from us in vContext.User
                           where us.IdUser == objUser.IdUser
                           select us).First();

            vResult.IdEmployee = objUser.IdEmployee;
            vResult.IdRole = objUser.IdRole;
            vResult.IdUser = objUser.IdUser;
            vResult.IsActive = objUser.IsActive;
            vResult.Password = objUser.Password;
            vResult.UserName = objUser.UserName;

            vContext.SaveChanges();
        }

        public void DeleteUser(User objUser)
        {
            var vResult = (from us in vContext.User
                           where us.IdUser == objUser.IdUser
                           select us).First();                      
            vContext.DeleteObject(vResult);
            vContext.SaveChanges();
        }

        public List<User> GetUsersList(long userId)
        {
            List<User> colModules = new List<User>();

            var vResult = (from us in vContext.User
                           .Include("Employee")
                           .Include("Role")
                           where us.IsActive == true && us.IdUser != userId
                           select us);
            if (vResult != null)
                colModules = new List<User>(vResult.AsEnumerable<User>());

            return colModules;
        }

        public User AuthenticatedUser(string userName, string userPassword)
        {
            try
            {
                var userFind = (from d in vContext.User
                                where d.UserName == userName
                                select d).FirstOrDefault();
                if (userFind != null)
                {
                    if (HashHelper.GeneratePasswordHash(userPassword) != userFind.Password)
                        throw new Exception("La contraseña ingresada no pertenece a este usuario.");

                    DealerStoreManager dealerMgr = new DealerStoreManager(true);
                    DealerStore objDealerStore = dealerMgr.GetDealerStoreByIdUser(userFind.IdUser);
                    if (objDealerStore != null)
                    {
                        userFind.IdDealerStore = objDealerStore.IdDealerStore;
                        userFind.DealerStoreName = objDealerStore.Name;
                        userFind.IdStore = objDealerStore.IdStore;
                        userFind.StoreName = objDealerStore.Store.Name;
                    }
                    CurrencyExchangeRatesManager exchangeMgr = new CurrencyExchangeRatesManager();
                    CurrencyExchangeRates objCurrentRate = exchangeMgr.CurrencyExchangeRatesGetByIdMoneyAndDate((long)MoneyEnum.ExternalMoney, DateTime.Today);
                    if (objCurrentRate != null)
                        userFind.CurrentCurrencyExchange = objCurrentRate.BuyExchangeRate;
                }
                else
                    throw new Exception("El nombre de usuario ingresado no se encuentra registrado en el sistema.");

                return userFind;
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public List<SystemModule> GetUserModules(string vUserName)
        {
            List<SystemModule> colModules = new List<SystemModule>();
            var modulesResult = (from cm in vContext.Command
                                 join sm in vContext.SystemModule on cm.IdSystemModule equals sm.IdSystemModule
                                 join cr in vContext.CommandInRole on cm.IdCommand equals cr.IdCommand
                                 join rl in vContext.Role on cr.IdRole equals rl.IdRole
                                 join us in vContext.User on rl.IdRole equals us.IdRole
                                 where us.UserName == vUserName
                                 select sm).Distinct();

            if (modulesResult != null)
                colModules = new List<SystemModule>(modulesResult.AsEnumerable<SystemModule>());

            return colModules;
        }

        public List<Command> GetUserCommands(string vUserName)
        {
            List<Command> colModules = new List<Command>();
            var modulesResult = (from cm in vContext.Command
                                 join sm in vContext.SystemModule on cm.IdSystemModule equals sm.IdSystemModule
                                 join cr in vContext.CommandInRole on cm.IdCommand equals cr.IdCommand
                                 join rl in vContext.Role on cr.IdRole equals rl.IdRole
                                 join us in vContext.User on rl.IdRole equals us.IdRole
                                 where us.UserName == vUserName
                                 orderby cm.Parent,cm.OrderBy
                                 select cm).Distinct();

            if (modulesResult != null)
                colModules = new List<Command>(modulesResult.AsEnumerable<Command>());            

            return colModules;
        }

        public List<Command> GetAllCommands()
        {
            List<Command> colModules = new List<Command>();
            var modulesResult = (from cm in vContext.Command
                                 select cm).Distinct();

            if (modulesResult != null)
                colModules = new List<Command>(modulesResult.AsEnumerable<Command>());

            return colModules;
        }

        public List<long> GetCommandsInRole(long idRole)
        {
            List<long> colCommands = new List<long>();
            var modulesResult = (from cr in vContext.CommandInRole
                                 join rl in vContext.Role on cr.IdRole equals rl.IdRole
                                 where rl.IdRole == idRole                                 
                                 select cr.IdCommand);

            if (modulesResult != null)
                colCommands = new List<long>(modulesResult.AsEnumerable<long>());
            return colCommands;
        }

        public void UpdateCommandForRole(long idRole, IList<long> colNewCommands)
        {
            var commandsOld = (from cr in vContext.CommandInRole
                                 join rl in vContext.Role on cr.IdRole equals rl.IdRole
                                 where rl.IdRole == idRole
                                 select cr);
            foreach (CommandInRole objRole in commandsOld.AsEnumerable<CommandInRole>())
            {
                vContext.DeleteObject(objRole);
            }

            foreach (long idCommand in colNewCommands)
            {
                CommandInRole objNewRole = new CommandInRole();
                objNewRole.IdCommand = idCommand;
                objNewRole.IdRole = idRole;
                vContext.AddObject("CommandInRole", objNewRole);
            }

            vContext.SaveChanges();
        }

        public void GeneratedNewPassword(long idUser)
        {
            var vResult = (from us in vContext.User
                           where us.IdUser == idUser
                           select us).FirstOrDefault();

            if (vResult != null)
            {
                vResult.GeneratedPassword = true;
                vResult.Password = HashHelper.GeneratePasswordHash("123");
                vContext.SaveChanges();
            }
        }

        public void ChangeUserPassword(long idUser, List<string> newPasswordData)
        {
            var vResult = (from us in vContext.User
                           where us.IdUser == idUser
                           select us).FirstOrDefault();

            if (vResult != null)
            {
                if (HashHelper.GeneratePasswordHash(newPasswordData[0]) != vResult.Password)
                    throw new Exception("La contraseña antigua ingresada no pertenece a este usuario.");

                vResult.GeneratedPassword = false;
                vResult.Password = HashHelper.GeneratePasswordHash(newPasswordData[1]);
                vContext.SaveChanges();
            }
        }
    }
}
